/*
* task_scheduler.c
*
*  Created on: Jul 26, 2024
*      Author: vuxtvg@163.com
*/

#include "task_scheduler.h"

#define HASH_TABLE_SIZE 17

typedef struct HashNode
{
        void (*pTaskFuncCb)(void);
        TaskComps_t *taskComp;
        struct HashNode *next;
} HashNode_t;

HashNode_t *hashTable[HASH_TABLE_SIZE];

uint32_t HashFunc(void (*taskFunc)(void))
{
        return ((uintptr_t) taskFunc) % HASH_TABLE_SIZE;
}

void HashTableInsert(void (*taskFunc)(void), TaskComps_t *taskComp)
{
        uint32_t index = HashFunc(taskFunc);
        HashNode_t *newNode = (HashNode_t*) malloc(sizeof(HashNode_t));
        newNode->pTaskFuncCb = taskFunc;
        newNode->taskComp = taskComp;
        newNode->next = hashTable[index];
        hashTable[index] = newNode;
}

void InitHashTable(void)
{
        for (uint8_t i = 0; i < HASH_TABLE_SIZE; i++)
        {
                hashTable[i] = NULL;
        }

        for (uint8_t i = 0; i < TASK_NUM_MAX; i++)
        {
                HashTableInsert(g_taskComps[i].pTaskFuncCb, g_taskComps+i);
        }
}

TaskComps_t* HashTableSearch(void (*taskFunc)(void))
{
        uint32_t index = HashFunc(taskFunc);
        HashNode_t *node = hashTable[index];
        while (node)
        {
                if (node->pTaskFuncCb == taskFunc)
                {
                        return node->taskComp;
                }
                node = node->next;
        }
        return NULL;
}

void FreeHashTable(void)
{
        for (uint8_t i = 0; i < HASH_TABLE_SIZE; i++)
        {
                HashNode_t *node = hashTable[i];
                while (node)
                {
                        HashNode_t *temp = node;
                        node = node->next;
                        free(temp);
                }
                hashTable[i] = NULL;
        }
}

void TaskHandler(void)
{
        for (uint8_t i = 0; i < TASK_NUM_MAX; i++)
        {
                if (g_taskComps[i].run && g_taskComps[i].enabled)
                {
                        g_taskComps[i].run = 0;
                        g_taskComps[i].runCount++;
                        g_taskComps[i].pTaskFuncCb();
                }
        }
}

void TaskScheduleCb(void)
{
        for (uint8_t i = 0; i < TASK_NUM_MAX; i++)
        {
                if (g_taskComps[i].timCount && g_taskComps[i].enabled)
                {
                        g_taskComps[i].timCount--;
                        if (g_taskComps[i].timCount == 0)
                        {
                                g_taskComps[i].run = 1;
                                g_taskComps[i].timCount = g_taskComps[i].timRload;
                        }
                }
        }
}

void SetTaskEnabled(void (*taskFunc)(void), uint8_t state)
{
        TaskComps_t *taskComp = HashTableSearch(taskFunc);
        if (taskComp)
        {
                taskComp->enabled = state;
        }
}

uint32_t GetTaskRunCount(void (*taskFunc)(void))
{
        TaskComps_t *taskComp = HashTableSearch(taskFunc);
        if (taskComp)
        {
                return taskComp->runCount;
        }
        return 0;  // 如果没有找到匹配的任务函数，返回0
}

void ExecuteOnMultiple(void (*taskFunc)(void), uint32_t multiple,
                void (*ActionFunc)(void))
{
        uint32_t runCount = GetTaskRunCount(taskFunc);
        if (runCount % multiple == 0)
        {
                ActionFunc();
        }
}

void TaskInit(void)
{
//        TaskScheduleCbReg(TaskScheduleCb);
        InitHashTable();
}
